home *** CD-ROM | disk | FTP | other *** search
/ Enter 2006 September / Enter 09 2006.iso / Internet / SpamExperts Home 1.1 / SpamExperts Home.exe / lib / spamexperts.modules / ZODB / broken.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2006-07-14  |  9.6 KB  |  334 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''Broken object support
  5.  
  6. $Id: broken.py 29446 2005-03-11 22:07:51Z tim_one $
  7. '''
  8. import sys
  9. import persistent
  10. broken_cache = { }
  11.  
  12. class Broken(object):
  13.     """Broken object base class
  14.  
  15.        Broken objects are placeholders for objects that can no longer be
  16.        created because their class has gone away.
  17.  
  18.        Broken objects don't really do much of anything, except hold their
  19.        state.   The Broken class is used as a base class for creating
  20.        classes in leu of missing classes::
  21.  
  22.          >>> Atall = type('Atall', (Broken, ), {'__module__': 'not.there'})
  23.  
  24.        The only thing the class can be used for is to create new objects::
  25.  
  26.          >>> Atall()
  27.          <broken not.there.Atall instance>
  28.          >>> Atall().__Broken_newargs__
  29.          ()
  30.          >>> Atall().__Broken_initargs__
  31.          ()
  32.  
  33.          >>> Atall(1, 2).__Broken_newargs__
  34.          (1, 2)
  35.          >>> Atall(1, 2).__Broken_initargs__
  36.          (1, 2)
  37.  
  38.          >>> a = Atall.__new__(Atall, 1, 2)
  39.          >>> a
  40.          <broken not.there.Atall instance>
  41.          >>> a.__Broken_newargs__
  42.          (1, 2)
  43.          >>> a.__Broken_initargs__
  44.  
  45.        You can't modify broken objects::
  46.  
  47.          >>> a.x = 1
  48.          Traceback (most recent call last):
  49.          ...
  50.          BrokenModified: Can't change broken objects
  51.  
  52.        But you can set their state::
  53.  
  54.          >>> a.__setstate__({'x': 1, })
  55.  
  56.        You can pickle broken objects::
  57.  
  58.          >>> r = a.__reduce__()
  59.          >>> len(r)
  60.          3
  61.          >>> r[0] is rebuild
  62.          True
  63.          >>> r[1]
  64.          ('not.there', 'Atall', 1, 2)
  65.          >>> r[2]
  66.          {'x': 1}
  67.  
  68.          >>> import cPickle
  69.          >>> a2 = cPickle.loads(cPickle.dumps(a, 1))
  70.          >>> a2
  71.          <broken not.there.Atall instance>
  72.          >>> a2.__Broken_newargs__
  73.          (1, 2)
  74.          >>> a2.__Broken_initargs__
  75.          >>> a2.__Broken_state__
  76.          {'x': 1}
  77.  
  78.        Cleanup::
  79.  
  80.          >>> broken_cache.clear()
  81.        """
  82.     __Broken_state__ = __Broken_initargs__ = None
  83.     __name__ = 'broken object'
  84.     
  85.     def __new__(class_, *args):
  86.         result = object.__new__(class_)
  87.         result.__dict__['__Broken_newargs__'] = args
  88.         return result
  89.  
  90.     
  91.     def __init__(self, *args):
  92.         self.__dict__['__Broken_initargs__'] = args
  93.  
  94.     
  95.     def __reduce__(self):
  96.         '''We pickle broken objects in hope of being able to fix them later
  97.         '''
  98.         return (rebuild, (self.__class__.__module__, self.__class__.__name__) + self.__Broken_newargs__, self.__Broken_state__)
  99.  
  100.     
  101.     def __setstate__(self, state):
  102.         self.__dict__['__Broken_state__'] = state
  103.  
  104.     
  105.     def __repr__(self):
  106.         return '<broken %s.%s instance>' % (self.__class__.__module__, self.__class__.__name__)
  107.  
  108.     
  109.     def __setattr__(self, name, value):
  110.         raise BrokenModified("Can't change broken objects")
  111.  
  112.  
  113.  
  114. def find_global(modulename, globalname, Broken = Broken, type = type):
  115.     '''Find a global object, returning a broken class if it can\'t be found.
  116.  
  117.        This function looks up global variable in modules::
  118.  
  119.          >>> import sys
  120.          >>> find_global(\'sys\', \'path\') is sys.path
  121.          True
  122.  
  123.        If an object can\'t be found, a broken class is returned::
  124.  
  125.          >>> broken = find_global(\'ZODB.not.there\', \'atall\')
  126.          >>> issubclass(broken, Broken)
  127.          True
  128.          >>> broken.__module__
  129.          \'ZODB.not.there\'
  130.          >>> broken.__name__
  131.          \'atall\'
  132.  
  133.        Broken classes are cached::
  134.  
  135.          >>> find_global(\'ZODB.not.there\', \'atall\') is broken
  136.          True
  137.  
  138.        If we "repair" a missing global::
  139.  
  140.          >>> class ZODBnotthere:
  141.          ...     atall = []
  142.  
  143.          >>> sys.modules[\'ZODB.not\'] = ZODBnotthere
  144.          >>> sys.modules[\'ZODB.not.there\'] = ZODBnotthere
  145.  
  146.        we can then get the repaired value::
  147.  
  148.          >>> find_global(\'ZODB.not.there\', \'atall\') is ZODBnotthere.atall
  149.          True
  150.  
  151.        Of course, if we beak it again::
  152.  
  153.          >>> del sys.modules[\'ZODB.not\']
  154.          >>> del sys.modules[\'ZODB.not.there\']
  155.  
  156.        we get the broken value::
  157.  
  158.          >>> find_global(\'ZODB.not.there\', \'atall\') is broken
  159.          True
  160.  
  161.        Cleanup::
  162.  
  163.          >>> broken_cache.clear()
  164.        '''
  165.     
  166.     try:
  167.         __import__(modulename)
  168.     except ImportError:
  169.         pass
  170.  
  171.     module = sys.modules[modulename]
  172.     
  173.     try:
  174.         return getattr(module, globalname)
  175.     except AttributeError:
  176.         pass
  177.  
  178.     
  179.     try:
  180.         return broken_cache[(modulename, globalname)]
  181.     except KeyError:
  182.         pass
  183.  
  184.     class_ = type(globalname, (Broken,), {
  185.         '__module__': modulename })
  186.     broken_cache[(modulename, globalname)] = class_
  187.     return class_
  188.  
  189.  
  190. def rebuild(modulename, globalname, *args):
  191.     '''Recreate a broken object, possibly recreating the missing class
  192.  
  193.        This functions unpickles broken objects::
  194.  
  195.          >>> broken = rebuild(\'ZODB.notthere\', \'atall\', 1, 2)
  196.          >>> broken
  197.          <broken ZODB.notthere.atall instance>
  198.          >>> broken.__Broken_newargs__
  199.          (1, 2)
  200.  
  201.        If we "repair" the brokenness::
  202.  
  203.          >>> class notthere: # fake notthere module
  204.          ...     class atall(object):
  205.          ...         def __new__(self, *args):
  206.          ...             ob = object.__new__(self)
  207.          ...             ob.args = args
  208.          ...             return ob
  209.          ...         def __repr__(self):
  210.          ...             return \'atall %s %s\' % self.args
  211.  
  212.          >>> sys.modules[\'ZODB.notthere\'] = notthere
  213.  
  214.          >>> rebuild(\'ZODB.notthere\', \'atall\', 1, 2)
  215.          atall 1 2
  216.  
  217.          >>> del sys.modules[\'ZODB.notthere\']
  218.  
  219.        Cleanup::
  220.  
  221.          >>> broken_cache.clear()
  222.  
  223.        '''
  224.     class_ = find_global(modulename, globalname)
  225.     return class_.__new__(class_, *args)
  226.  
  227.  
  228. class BrokenModified(TypeError):
  229.     '''Attempt to modify a broken object
  230.     '''
  231.     pass
  232.  
  233.  
  234. class PersistentBroken(Broken, persistent.Persistent):
  235.     """Persistent broken objects
  236.  
  237.         Persistent broken objects are used for broken objects that are
  238.         also persistent.  In addition to having to track the original
  239.         object data, they need to handle persistent meta data.
  240.  
  241.         Persistent broken classes are created from existing broken classes
  242.         using the persistentBroken, function::
  243.  
  244.           >>> Atall = type('Atall', (Broken, ), {'__module__': 'not.there'})
  245.           >>> PAtall = persistentBroken(Atall)
  246.  
  247.         (Note that we always get the *same* persistent broken class
  248.          for a given broken class::
  249.  
  250.           >>> persistentBroken(Atall) is PAtall
  251.           True
  252.  
  253.          )
  254.  
  255.         Persistent broken classes work a lot like broken classes::
  256.  
  257.           >>> a = PAtall.__new__(PAtall, 1, 2)
  258.           >>> a
  259.           <persistent broken not.there.Atall instance None>
  260.           >>> a.__Broken_newargs__
  261.           (1, 2)
  262.           >>> a.__Broken_initargs__
  263.           >>> a.x = 1
  264.           Traceback (most recent call last):
  265.           ...
  266.           BrokenModified: Can't change broken objects
  267.  
  268.         Unlike regular broken objects, persistent broken objects keep
  269.         track of persistence meta data:
  270.  
  271.           >>> a._p_oid = '\\0\\0\\0\\0****'
  272.           >>> a
  273.           <persistent broken not.there.Atall instance '\\x00\\x00\\x00\\x00****'>
  274.  
  275.         and persistent broken objects aren't directly picklable:
  276.  
  277.           >>> a.__reduce__()
  278.           Traceback (most recent call last):
  279.           ...
  280.           BrokenModified: <persistent broken not.there.Atall instance '\\x00\\x00\\x00\\x00****'>
  281.  
  282.         but you can get their state:
  283.  
  284.           >>> a.__setstate__({'y': 2})
  285.           >>> a.__getstate__()
  286.           {'y': 2}
  287.  
  288.        Cleanup::
  289.  
  290.          >>> broken_cache.clear()
  291.  
  292.         """
  293.     
  294.     def __new__(class_, *args):
  295.         result = persistent.Persistent.__new__(class_)
  296.         result.__dict__['__Broken_newargs__'] = args
  297.         return result
  298.  
  299.     
  300.     def __reduce__(self, *args):
  301.         raise BrokenModified(self)
  302.  
  303.     
  304.     def __getstate__(self):
  305.         return self.__Broken_state__
  306.  
  307.     
  308.     def __setattr__(self, name, value):
  309.         if name.startswith('_p_'):
  310.             persistent.Persistent.__setattr__(self, name, value)
  311.         else:
  312.             raise BrokenModified("Can't change broken objects")
  313.  
  314.     
  315.     def __repr__(self):
  316.         return '<persistent broken %s.%s instance %r>' % (self.__class__.__module__, self.__class__.__name__, self._p_oid)
  317.  
  318.     
  319.     def __getnewargs__(self):
  320.         return self.__Broken_newargs__
  321.  
  322.  
  323.  
  324. def persistentBroken(class_):
  325.     
  326.     try:
  327.         return class_.__dict__['__Broken_Persistent__']
  328.     except KeyError:
  329.         class_.__Broken_Persistent__ = type(class_.__name__, (PersistentBroken, class_), {
  330.             '__module__': class_.__module__ })
  331.         return class_.__dict__['__Broken_Persistent__']
  332.  
  333.  
  334.